home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 6 / tcfun1.zip / DIRSEL.C next >
Text File  |  1987-07-13  |  18KB  |  523 lines

  1. #include "STDIO.h"
  2. #include "STDLIB.h"
  3. #include "IO.h"
  4. #include "FCNTL.h"
  5. #include "DOS.h"
  6. #include "DIR.h"
  7.  
  8. /*
  9.     DIRSEL.c   v1.00    Vernon E. Davis
  10.     07/12/87            17 South Centre Street
  11.                         Merchantville, NJ 08109
  12.                         CompuServe [71330,2705]
  13.                         GEnie - VED
  14.  
  15.  
  16.     purpose   : to select one filename from the list presented
  17.     syntax    : #include "STDIO.h"
  18.               : #include "STDLIB.h"
  19.               : #include "IO.h"
  20.               : #include "FCNTL.h"
  21.               : #include "DOS.h"
  22.               : #include "DIR.h"
  23.               : *p = dirselect(*mask,attr);
  24.               : char *p;     the filename
  25.               : char *mask;  the directory mask, i.e. "*.*"
  26.               : int attr;    the attribute to look for,i.e.
  27.               :               FA_RDONLY, FA_HIDDEN, FA_SYSTEM,
  28.               :               FA_LABEL,  FA_DIREC,  FA_ARCH.
  29.               :               (see dos.h or Turbo C manual for info.)
  30.               :
  31.     returns   : either a pointer to a filename that was selected or
  32.               : NULL if Escape was pressed and if no file is found.
  33.               :
  34.     descrip.  : a call to dirselect() first determines if there are any files
  35.               : that meet the specs received from the directory mask. If
  36.               : no files were found, the function immediately returns NULL.
  37.               : Otherwise, all filenames that meet the mask spec are copyed
  38.               : into an array that can hold up to 120 selections. The routine
  39.               : then clears a portion of the screen, saving the contents of
  40.               : the screen in an array. A frame is drawn in the cleared portion
  41.               : of the screen and the current directory contents are displayed
  42.               : in the boxed area as per the  mask that was received. The first
  43.               : selection is highlighted in reverse video. The up/down/left/
  44.               : right arrow keys will move the highlight around.  The Home Key
  45.               : returns to the first selection. The End key moves to the last
  46.               : selection. When < CR > is pressed,  the screen returns to
  47.               : normal, the cursor is placed in its original position and the
  48.               : value returned from the function is a pointer to a string
  49.               : containing the filename selected.  If Esc was pressed instead,
  50.               : the previous sequence is performed, with the exception of NULL
  51.               : being returned instead of the filename.
  52.               :
  53.     notes     : A. All routines in this file can be run under TC, the
  54.               :    Turbo C Integrated Development Environment. Because of
  55.               :    this, the routine will run slow when executed. It was
  56.               :    not designed for speed.
  57.               : B. These routines rely on the video hardware interrupt 0x10
  58.               :    for the cursor information. Insure that the PC is an IBM
  59.               :    or compatable.
  60.               : C. Three (3) cursor functions and a frame drawing function are
  61.               :    available. They are as follows:
  62.               :    1. void     gotoxy(x,y); move cursor to new location
  63.               :                int x (0..79)
  64.               :                int y (0..24)
  65.               :    2. void     cursor(ON/OFF); turn cursor on or off
  66.               :                int ON (1) or OFF (0)
  67.               :    3. xyposdef wherecur(void); locate cursor position
  68.               :                xyposdef.x (0..79)  column location
  69.               :                xyposdef.y (0..24)  row location
  70.               :    4. void     drframe(top,left,bottom,right); draw double fr.
  71.               :                int top    (0..24)  top corner
  72.               :                int left   (0..79)  left corner
  73.               :                int bottom (0..24)  bottom corner
  74.               :                int right  (0..79)  right corner
  75.               :    The other functions declared are special to dirselect()
  76.               :    and of no real use; however, they are documented.
  77. */
  78.  
  79. #define TRUE 1
  80. #define FALSE 0
  81. #define ON 1
  82. #define OFF 0
  83. #define VIDINTR 0x10
  84. #define EQUINTR 0x11
  85. #define FPOS1  1
  86. #define FPOS2 14
  87. #define FPOS3 27
  88. #define FPOS4 40
  89. #define FPOS5 53
  90. #define FPOS6 66
  91.  
  92.    typedef struct     /* structure for directory array */
  93.    {  char fname[13];
  94.    }  dirdef;
  95.  
  96.    typedef struct     /* structure for cursor column(x) and row(y) */
  97.    {  int x,y;
  98.    }  xyposdef;
  99.  
  100. /*  function declarations  */
  101.  
  102. char* dirselect(char*,int);                   /* the main function */
  103. void hilite(unsigned char,unsigned char);     /* highlights the filename */
  104. xyposdef fnamepos(unsigned char);             /* X/Y position of filename */
  105. void drframe(int,int,int,int);                /* draw double-line frame */
  106. void gotoxy(unsigned char,unsigned char);     /* move cursor to new location */
  107. void cursor(int);                             /* turn cursor on or off */
  108. xyposdef wherecur(void);                      /* current cursor location */
  109.  
  110. char* dirselect(mask,attr)
  111.    char mask[13];
  112.    int attr;
  113. {  union REGS regs;
  114.    struct ffblk ffblk;
  115.    int h,i,j,k,row,error,oldcurx,oldcury;
  116.    unsigned char oldpos,newpos;
  117.    char chrbuf[4000],atrbuf[4000];
  118.    char key;
  119.    dirdef dos_dir[121],*dos_dirptr;
  120.    xyposdef xypos;
  121.    h=0;
  122.    if((error=findfirst(mask,&ffblk,attr))==-1) /* if not found, return NULL */
  123.       return(NULL);
  124.    while(!error&&h!=120)        /* else, collect filenames */
  125.    {  dos_dirptr=&dos_dir[h++];
  126.       strcpy(dos_dirptr->fname,ffblk.ff_name);
  127.       error=findnext(&ffblk);
  128.    };
  129.    xypos=wherecur();     /* store old cursor position */
  130.    oldcurx=xypos.x;
  131.    oldcury=xypos.y;
  132.    cursor(OFF);
  133.    k=0;
  134.    for(i=0;i<((h/6)+3);i++)   /* store old screen info & clear portion */
  135.    {  for(j=0;j<80;j++)
  136.       {  gotoxy(j,i);
  137.          regs.h.bh=0;
  138.          regs.h.ah=8;
  139.          int86(VIDINTR,®s,®s);
  140.          chrbuf[k]=regs.h.al;
  141.          atrbuf[k]=regs.h.ah;
  142.          putch(32);
  143.          k++;
  144.       };
  145.    };
  146.    gotoxy(0,0);
  147.    i=0; j=0; row=1;
  148.    while(TRUE)                  /* display all filenames */
  149.    {  dos_dirptr=&dos_dir[i];
  150.       xypos=fnamepos(i);
  151.       gotoxy(xypos.x,xypos.y);
  152.       printf("%-012.12s",dos_dirptr->fname);
  153.       i++; j++;
  154.       if(i==h||i==120) break;
  155.       if(j>5)
  156.       {  j=0;
  157.          row++;
  158.          printf("\n");
  159.       };
  160.    };
  161.    drframe(0,0,(row+1),79);  /* draw the frame */
  162.    hilite(255,0);            /* highlight the first filename */
  163.    oldpos=0;
  164.    newpos=0;
  165.    while(TRUE)           /* get keypress and do appropriate action */
  166.    {  key=getch();
  167.       switch(key)
  168.       {  case 27:  /* Esc  */
  169.             k=0;
  170.             for(i=0;i<((h/6)+3);i++)  /* return contents of old screen */
  171.             {  for(j=0;j<80;j++)
  172.                {  gotoxy(j,i);
  173.                   regs.h.al=chrbuf[k];
  174.                   regs.h.bl=atrbuf[k];
  175.                   regs.h.ch=0;
  176.                   regs.h.cl=1;
  177.                   regs.h.bh=0;
  178.                   regs.h.ah=9;
  179.                   int86(VIDINTR,®s,®s);
  180.                   k++;
  181.                };
  182.             };
  183.             gotoxy(oldcurx,oldcury);         /* return old cursor position */
  184.             cursor(ON);
  185.             return(NULL);                    /* return NULL */
  186.          case 71:  /* Home */                /* goto first filename */
  187.             oldpos=newpos;
  188.             newpos=0;
  189.             hilite(oldpos,newpos);
  190.             break;
  191.          case 79:  /* End  */                /* goto last filename */
  192.             oldpos=newpos;
  193.             newpos=(h-1);
  194.             hilite(oldpos,newpos);
  195.             break;
  196.          case 72:  /* Up   */                /* move up one filename */
  197.             i=newpos;
  198.             i-=6;
  199.             if(i>=0)
  200.             {  oldpos=newpos;
  201.                newpos=i;
  202.                hilite(oldpos,newpos);
  203.             };
  204.             break;
  205.          case 80:  /* Down */                /* move down one filename */
  206.             i=newpos;
  207.             i+=6;
  208.             if(i<h)
  209.             {  oldpos=newpos;
  210.                newpos=i;
  211.                hilite(oldpos,newpos);
  212.             };
  213.             break;
  214.          case 75:  /* Left */                /* move left one filename */
  215.             i=newpos;
  216.             i--;
  217.             if(i>=0)
  218.             {  oldpos=newpos;
  219.                newpos=i;
  220.                hilite(oldpos,newpos);
  221.             };
  222.             break;
  223.          case 77:  /* Right */               /* move right one filename */
  224.             i=newpos;
  225.             i++;
  226.             if(i<h)
  227.             {  oldpos=newpos;
  228.                newpos=i;
  229.                hilite(oldpos,newpos);
  230.             };
  231.             break;
  232.          case 13:  /* CR */
  233.             k=0;
  234.             for(i=0;i<((h/6)+3);i++)       /* return contents of old screen */
  235.             {  for(j=0;j<80;j++)
  236.                {  gotoxy(j,i);
  237.                   regs.h.al=chrbuf[k];
  238.                   regs.h.bl=atrbuf[k];
  239.                   regs.h.ch=0;
  240.                   regs.h.cl=1;
  241.                   regs.h.bh=0;
  242.                   regs.h.ah=9;
  243.                   int86(VIDINTR,®s,®s);
  244.                   k++;
  245.                };
  246.             };
  247.             gotoxy(oldcurx,oldcury);    /* return old cursor position */
  248.             cursor(ON);
  249.             return(dos_dir[newpos].fname);   /* return with filename */
  250.       };
  251.    };
  252. }
  253.  
  254. void hilite(old,new)         /* highlight a filename on the screen */
  255.    unsigned char old,new;
  256. {  union REGS regs;
  257.    int oldx,oldy,newx,newy,i;
  258.    unsigned char ccolor,locolor,hicolor;
  259.    xyposdef xypos;
  260.    xypos=fnamepos(old);
  261.    oldx=xypos.x;
  262.    oldy=xypos.y;
  263.    xypos=fnamepos(new);    /* get the position in the array of the filename */
  264.    newx=xypos.x;
  265.    newy=xypos.y;
  266.    for(i=0;i<12;i++)
  267.    {  if(old<121)       /* if valid position, reverse video, old selection */
  268.       {  gotoxy((oldx+i),oldy);
  269.          regs.h.bh=0;
  270.          regs.h.ah=8;
  271.          int86(VIDINTR,®s,®s);
  272.          ccolor=regs.h.ah;
  273.          locolor=ccolor&0x0F;
  274.          locolor<<=4;
  275.          hicolor=ccolor&0xF0;
  276.          hicolor>>=4;
  277.          ccolor=locolor+hicolor;
  278.          regs.h.ch=0;
  279.          regs.h.cl=1;
  280.          regs.h.bh=0;
  281.          regs.h.bl=ccolor;
  282.          regs.h.ah=9;
  283.          int86(VIDINTR,®s,®s);
  284.       };
  285.       gotoxy((newx+i),newy);         /* reverse video, new selection */
  286.       regs.h.bh=0;
  287.       regs.h.ah=8;
  288.       int86(VIDINTR,®s,®s);
  289.       ccolor=regs.h.ah;
  290.       locolor=ccolor&0x0F;
  291.       locolor<<=4;
  292.       hicolor=ccolor&0xF0;
  293.       hicolor>>=4;
  294.       ccolor=locolor+hicolor;
  295.       regs.h.ch=0;
  296.       regs.h.cl=1;
  297.       regs.h.bh=0;
  298.       regs.h.bl=ccolor;
  299.       regs.h.ah=9;
  300.       int86(VIDINTR,®s,®s);
  301.    };
  302.    return;
  303. }
  304.  
  305. xyposdef fnamepos(arypos)   /* determine position on screen of filename[] */
  306.    unsigned char arypos;
  307. {  int x,y;
  308.    xyposdef xyp;
  309.    switch(arypos)
  310.    {  case   0: x=FPOS1; y= 1; break;   /* see #define for x coordinates */
  311.       case   1: x=FPOS2; y= 1; break;
  312.       case   2: x=FPOS3; y= 1; break;
  313.       case   3: x=FPOS4; y= 1; break;
  314.       case   4: x=FPOS5; y= 1; break;
  315.       case   5: x=FPOS6; y= 1; break;
  316.       case   6: x=FPOS1; y= 2; break;
  317.       case   7: x=FPOS2; y= 2; break;
  318.       case   8: x=FPOS3; y= 2; break;
  319.       case   9: x=FPOS4; y= 2; break;
  320.       case  10: x=FPOS5; y= 2; break;
  321.       case  11: x=FPOS6; y= 2; break;
  322.       case  12: x=FPOS1; y= 3; break;
  323.       case  13: x=FPOS2; y= 3; break;
  324.       case  14: x=FPOS3; y= 3; break;
  325.       case  15: x=FPOS4; y= 3; break;
  326.       case  16: x=FPOS5; y= 3; break;
  327.       case  17: x=FPOS6; y= 3; break;
  328.       case  18: x=FPOS1; y= 4; break;
  329.       case  19: x=FPOS2; y= 4; break;
  330.       case  20: x=FPOS3; y= 4; break;
  331.       case  21: x=FPOS4; y= 4; break;
  332.       case  22: x=FPOS5; y= 4; break;
  333.       case  23: x=FPOS6; y= 4; break;
  334.       case  24: x=FPOS1; y= 5; break;
  335.       case  25: x=FPOS2; y= 5; break;
  336.       case  26: x=FPOS3; y= 5; break;
  337.       case  27: x=FPOS4; y= 5; break;
  338.       case  28: x=FPOS5; y= 5; break;
  339.       case  29: x=FPOS6; y= 5; break;
  340.       case  30: x=FPOS1; y= 6; break;
  341.       case  31: x=FPOS2; y= 6; break;
  342.       case  32: x=FPOS3; y= 6; break;
  343.       case  33: x=FPOS4; y= 6; break;
  344.       case  34: x=FPOS5; y= 6; break;
  345.       case  35: x=FPOS6; y= 6; break;
  346.       case  36: x=FPOS1; y= 7; break;
  347.       case  37: x=FPOS2; y= 7; break;
  348.       case  38: x=FPOS3; y= 7; break;
  349.       case  39: x=FPOS4; y= 7; break;
  350.       case  40: x=FPOS5; y= 7; break;
  351.       case  41: x=FPOS6; y= 7; break;
  352.       case  42: x=FPOS1; y= 8; break;
  353.       case  43: x=FPOS2; y= 8; break;
  354.       case  44: x=FPOS3; y= 8; break;
  355.       case  45: x=FPOS4; y= 8; break;
  356.       case  46: x=FPOS5; y= 8; break;
  357.       case  47: x=FPOS6; y= 8; break;
  358.       case  48: x=FPOS1; y= 9; break;
  359.       case  49: x=FPOS2; y= 9; break;
  360.       case  50: x=FPOS3; y= 9; break;
  361.       case  51: x=FPOS4; y= 9; break;
  362.       case  52: x=FPOS5; y= 9; break;
  363.       case  53: x=FPOS6; y= 9; break;
  364.       case  54: x=FPOS1; y=10; break;
  365.       case  55: x=FPOS2; y=10; break;
  366.       case  56: x=FPOS3; y=10; break;
  367.       case  57: x=FPOS4; y=10; break;
  368.       case  58: x=FPOS5; y=10; break;
  369.       case  59: x=FPOS6; y=10; break;
  370.       case  60: x=FPOS1; y=11; break;
  371.       case  61: x=FPOS2; y=11; break;
  372.       case  62: x=FPOS3; y=11; break;
  373.       case  63: x=FPOS4; y=11; break;
  374.       case  64: x=FPOS5; y=11; break;
  375.       case  65: x=FPOS6; y=11; break;
  376.       case  66: x=FPOS1; y=12; break;
  377.       case  67: x=FPOS2; y=12; break;
  378.       case  68: x=FPOS3; y=12; break;
  379.       case  69: x=FPOS4; y=12; break;
  380.       case  70: x=FPOS5; y=12; break;
  381.       case  71: x=FPOS6; y=12; break;
  382.       case  72: x=FPOS1; y=13; break;
  383.       case  73: x=FPOS2; y=13; break;
  384.       case  74: x=FPOS3; y=13; break;
  385.       case  75: x=FPOS4; y=13; break;
  386.       case  76: x=FPOS5; y=13; break;
  387.       case  77: x=FPOS6; y=13; break;
  388.       case  78: x=FPOS1; y=14; break;
  389.       case  79: x=FPOS2; y=14; break;
  390.       case  80: x=FPOS3; y=14; break;
  391.       case  81: x=FPOS4; y=14; break;
  392.       case  82: x=FPOS5; y=14; break;
  393.       case  83: x=FPOS6; y=14; break;
  394.       case  84: x=FPOS1; y=15; break;
  395.       case  85: x=FPOS2; y=15; break;
  396.       case  86: x=FPOS3; y=15; break;
  397.       case  87: x=FPOS4; y=15; break;
  398.       case  88: x=FPOS5; y=15; break;
  399.       case  89: x=FPOS6; y=15; break;
  400.       case  90: x=FPOS1; y=16; break;
  401.       case  91: x=FPOS2; y=16; break;
  402.       case  92: x=FPOS3; y=16; break;
  403.       case  93: x=FPOS4; y=16; break;
  404.       case  94: x=FPOS5; y=16; break;
  405.       case  95: x=FPOS6; y=16; break;
  406.       case  96: x=FPOS1; y=17; break;
  407.       case  97: x=FPOS2; y=17; break;
  408.       case  98: x=FPOS3; y=17; break;
  409.       case  99: x=FPOS4; y=17; break;
  410.       case 100: x=FPOS5; y=17; break;
  411.       case 101: x=FPOS6; y=17; break;
  412.       case 102: x=FPOS1; y=18; break;
  413.       case 103: x=FPOS2; y=18; break;
  414.       case 104: x=FPOS3; y=18; break;
  415.       case 105: x=FPOS4; y=18; break;
  416.       case 106: x=FPOS5; y=18; break;
  417.       case 107: x=FPOS6; y=18; break;
  418.       case 108: x=FPOS1; y=19; break;
  419.       case 109: x=FPOS2; y=19; break;
  420.       case 110: x=FPOS3; y=19; break;
  421.       case 111: x=FPOS4; y=19; break;
  422.       case 112: x=FPOS5; y=19; break;
  423.       case 113: x=FPOS6; y=19; break;
  424.       case 114: x=FPOS1; y=20; break;
  425.       case 115: x=FPOS2; y=20; break;
  426.       case 116: x=FPOS3; y=20; break;
  427.       case 117: x=FPOS4; y=20; break;
  428.       case 118: x=FPOS5; y=20; break;
  429.       case 119: x=FPOS6; y=20; break;
  430.    };
  431.    xyp.x=x; xyp.y=y;
  432.    return(xyp);      /* return with X/Y coordinates of filename[] */
  433. }
  434.  
  435. void drframe(t,l,b,r)  /* draw a frame on the screen */
  436.    int t,l,b,r;
  437. {  int h,i;
  438.    gotoxy(l,t); printf("%c",201);  /* draw upper corners */
  439.    gotoxy(r,t); printf("%c",187);
  440.    gotoxy(l+1,t);
  441.    for(i=0;i<(r-(l+1));i++)  /* draw top bar */
  442.       printf("%c",205);
  443.    gotoxy(l+1,b);
  444.    for(i=0;i<(r-(l+1));i++)  /* draw bottom bar */
  445.       printf("%c",205);
  446.    gotoxy(l,b); printf("%c",200);  /* draw bottom corners */
  447.    gotoxy(r,b); printf("%c",188);
  448.    for(i=(t+1);i<b;i++)      /* draw left side bar */
  449.    {  gotoxy(l,i);
  450.       printf("%c",186);
  451.    };
  452.    for(i=(t+1);i<b;i++)      /* draw right side bar */
  453.    {  gotoxy(r,i);
  454.       printf("%c",186);
  455.    };
  456.    return;
  457. }
  458.  
  459. void cursor(mode)  /* turn the cursor on or off */
  460.    int mode;
  461. {  union REGS regs;
  462.    int i;
  463.    if(mode==OFF)
  464.    {  regs.h.cl=7;
  465.       regs.h.ch=32;    /* set bit 5 high to turn cursor off */
  466.    }
  467.    else
  468.    {  int86(EQUINTR,®s,®s);  /* get equipment to determine video mode */
  469.       i=regs.h.al;
  470.       regs.x.cx=0x0607;    /* prepare for CGA */
  471.       if((i&=0x10)!=NULL)  /* if MA/MGA */
  472.         regs.x.cx=0x0B0C;  /* prepare for MA/MGA */
  473.    };
  474.    regs.h.ah=1;
  475.    int86(VIDINTR,®s,®s);
  476.    return;
  477. };
  478.  
  479. void gotoxy(x,y)  /* move cursor to a new location */
  480.    unsigned char x,y;
  481. {  union REGS regs;
  482.    regs.h.bh=0;
  483.    regs.h.dl=x;
  484.    regs.h.dh=y;
  485.    regs.h.ah=2;
  486.    int86(VIDINTR,®s,®s);
  487.    return;
  488. }
  489.  
  490. xyposdef wherecur(void)  /* report current cursor location */
  491. {  union REGS regs;
  492.    xyposdef xyp;
  493.    regs.h.ah=3;
  494.    regs.h.bh=0;
  495.    int86(VIDINTR,®s,®s);
  496.    xyp.y=regs.h.dh;
  497.    xyp.x=regs.h.dl;
  498.    return(xyp);
  499. }
  500.  
  501. /*  End Of Function  dirselect()  */
  502.  
  503. /*  The following main() is only for demo purposes. It is not needed in
  504.     your own programs.  */
  505.  
  506. main()
  507. {  char fname[13],*name;
  508.    char fmask[13],*mask;
  509.    while(TRUE)
  510.    {  name=&fname[0];
  511.       mask=&fmask[0];
  512.       printf("Enter a directory mask => ");
  513.       gets(mask);
  514.       if((name=dirselect(mask,FA_ARCH))==NULL)
  515.       {  printf("\nNo file selected\nProgram aborted.\n");
  516.          break;
  517.       }
  518.       else
  519.          printf("The file you selected was %s.\n",name);
  520.    };
  521.    exit(0);
  522. }
  523.